package client

import (
	"context"
	"fmt"
	"time"

	pb "raftique/network/proto"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
)

// RaftClient 是 Raft 客户端
type RaftClient struct {
	conn   *grpc.ClientConn
	client pb.RaftServiceClient
}

// NewRaftClient 创建一个新的 Raft 客户端
func NewRaftClient(address string) (*RaftClient, error) {
	conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		return nil, fmt.Errorf("failed to connect: %v", err)
	}

	client := pb.NewRaftServiceClient(conn)
	return &RaftClient{
		conn:   conn,
		client: client,
	}, nil
}

// Close 关闭客户端连接
func (c *RaftClient) Close() error {
	if c.conn != nil {
		return c.conn.Close()
	}
	return nil
}

// AppendEntries 发送追加日志条目请求
func (c *RaftClient) AppendEntries(ctx context.Context, req *pb.AppendEntriesRequest) (*pb.AppendEntriesResponse, error) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	return c.client.AppendEntries(ctx, req)
}

// RequestVote 发送请求投票
func (c *RaftClient) RequestVote(ctx context.Context, req *pb.RequestVoteRequest) (*pb.RequestVoteResponse, error) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	return c.client.RequestVote(ctx, req)
}

// InstallSnapshot 发送安装快照请求
func (c *RaftClient) InstallSnapshot(ctx context.Context, req *pb.InstallSnapshotRequest) (*pb.InstallSnapshotResponse, error) {
	ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()
	return c.client.InstallSnapshot(ctx, req)
}
